package main

import (
	"fmt"
	"sync"
	"time"
)

var mutex sync.Mutex // 创建锁头
var wg sync.WaitGroup
var ticket int = 20 // 初始值100张票

func main() {
	//创建四个窗口进行售票
	fmt.Println("售票中")
	wg.Add(4)
	go ShopTicket(1)
	go ShopTicket(2)
	go ShopTicket(3)
	go ShopTicket(4)
	time.Sleep(5 * time.Second)
	wg.Wait()
	fmt.Println("所有窗口已售出")

}
func ShopTicket(Num int) {
	defer wg.Done() //还是可以用的
	// rand.Seed(time.Now().UnixNano()) //设置当前时间格式为纳秒
	for {

		mutex.Lock()
		if ticket > 0 {
			time.Sleep(10 * time.Millisecond) // 停留0.1秒（100毫秒）
			ticket -= 1
			fmt.Printf("%d窗口售出一张票,剩余数量为%d\n", Num, ticket)
		} else {
			mutex.Unlock() // 这里因为执行了break后,会导致其他协程被锁,因此也需要解锁
			fmt.Println(Num, "窗口没有票了")

			break
		}
		mutex.Unlock() // 解锁
	}
}

//因为可以四个方法一致,可以直接调用一个方法就行

// func ShopTicket2(Num int) {
// 	// defer wg.Done()

// 	for {
// 		if ticket > 0 {
// 			time.Sleep(100 * time.Millisecond) // 停留0.1秒（100毫秒）
// 			ticket--
// 			fmt.Printf("%d窗口售出一张票,剩余数量为%d\n", Num, ticket)
// 		} else {
// 			fmt.Println(Num, "窗口没有票了")
// 			wg.Done()
// 			break
// 		}
// 	}
// }
// func ShopTicket3(Num int) {
// 	// defer wg.Done()

// 	for {
// 		if ticket > 0 {

// 			time.Sleep(100 * time.Millisecond) // 停留0.1秒（100毫秒）
// 			ticket -= 1
// 			fmt.Printf("%d窗口售出一张票,剩余数量为%d\n", Num, ticket)
// 		} else {
// 			fmt.Println(Num, "窗口没有票了")
// 			wg.Done()
// 			break

// 		}
// 	}
// }
// func ShopTicket4(Num int) {
// 	// defer wg.Done()

// 	for {
// 		if ticket > 0 {
// 			time.Sleep(100 * time.Millisecond) // 停留0.1秒（100毫秒）
// 			ticket -= 1
// 			fmt.Printf("%d窗口售出一张票,剩余数量为%d\n", Num, ticket)
// 		} else {
// 			fmt.Println(Num, "窗口没有票了")
// 			wg.Done()
// 			break
// 		}
// 	}
// }
